package api

import (
	"net/http"
	"strconv"

	"GinAdmin/core/logger"
	"GinAdmin/model"
	"GinAdmin/service"

	"github.com/gin-gonic/gin"
)

// RoleAPI 角色API控制器
type RoleAPI struct {
	roleService *service.RoleService
}

// NewRoleAPI 创建角色API控制器
func NewRoleAPI() *RoleAPI {
	return &RoleAPI{
		roleService: service.NewRoleService(),
	}
}

// GetRoleList 获取角色列表
// @Summary 获取角色列表
// @Description 获取角色列表
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param name query string false "角色名称"
// @Param code query string false "角色编码"
// @Param status query int false "状态(1:启用,2:禁用)"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles [get]
func (a *RoleAPI) GetRoleList(c *gin.Context) {
	params := &model.RoleSearchParams{
		Name:   c.Query("name"),
		Code:   c.Query("code"),
		Status: 0,
	}

	if status, err := strconv.Atoi(c.DefaultQuery("status", "0")); err == nil {
		params.Status = status
	}

	roles, total, err := a.roleService.GetRoleList(params)
	if err != nil {
		logger.Error("获取角色列表失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取角色列表失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: model.PageResult{
			List:  roles,
			Total: total,
		},
	})
}

// GetRoleByID 获取角色详情
// @Summary 获取角色详情
// @Description 获取角色详情
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "角色ID"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles/{id} [get]
func (a *RoleAPI) GetRoleByID(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的角色ID",
		})
		return
	}

	role, err := a.roleService.GetRoleByID(uint(id))
	if err != nil {
		logger.Error("获取角色详情失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取角色详情失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: role,
	})
}

// CreateRole 创建角色
// @Summary 创建角色
// @Description 创建新角色
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param data body model.CreateRoleRequest true "角色信息"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles [post]
func (a *RoleAPI) CreateRole(c *gin.Context) {
	var req model.CreateRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "请求参数错误: " + err.Error(),
		})
		return
	}

	role, err := a.roleService.CreateRole(&req)
	if err != nil {
		logger.Error("创建角色失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "创建角色失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "创建成功",
		Data: role,
	})
}

// UpdateRole 更新角色
// @Summary 更新角色
// @Description 更新角色信息
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "角色ID"
// @Param data body model.UpdateRoleRequest true "角色信息"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles/{id} [put]
func (a *RoleAPI) UpdateRole(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的角色ID",
		})
		return
	}

	var req model.UpdateRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "请求参数错误: " + err.Error(),
		})
		return
	}

	role, err := a.roleService.UpdateRole(uint(id), &req)
	if err != nil {
		logger.Error("更新角色失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "更新角色失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "更新成功",
		Data: role,
	})
}

// DeleteRole 删除角色
// @Summary 删除角色
// @Description 删除角色
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "角色ID"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles/{id} [delete]
func (a *RoleAPI) DeleteRole(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的角色ID",
		})
		return
	}

	err = a.roleService.DeleteRole(uint(id))
	if err != nil {
		logger.Error("删除角色失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "删除角色失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "删除成功",
	})
}

// GetRoleMenus 获取角色菜单
// @Summary 获取角色菜单
// @Description 获取角色关联的菜单列表
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "角色ID"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles/{id}/menus [get]
func (a *RoleAPI) GetRoleMenus(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的角色ID",
		})
		return
	}

	menus, err := a.roleService.GetRoleMenus(uint(id))
	if err != nil {
		logger.Error("获取角色菜单失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "获取角色菜单失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "获取成功",
		Data: menus,
	})
}

// UpdateRoleMenus 更新角色菜单
// @Summary 更新角色菜单
// @Description 更新角色关联的菜单
// @Tags 角色管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "角色ID"
// @Param menuIds body []int true "菜单ID列表"
// @Success 200 {object} model.Response "成功"
// @Router /api/roles/{id}/menus [put]
func (a *RoleAPI) UpdateRoleMenus(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "无效的角色ID",
		})
		return
	}

	var menuIDs []uint
	if err := c.ShouldBindJSON(&menuIDs); err != nil {
		c.JSON(http.StatusBadRequest, model.Response{
			Code: 400,
			Msg:  "请求参数错误: " + err.Error(),
		})
		return
	}

	err = a.roleService.UpdateRoleMenus(uint(id), menuIDs)
	if err != nil {
		logger.Error("更新角色菜单失败: %v", err)
		c.JSON(http.StatusInternalServerError, model.Response{
			Code: 500,
			Msg:  "更新角色菜单失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.Response{
		Code: 200,
		Msg:  "更新成功",
	})
}
